import { defineConfig } from 'vite'
import path from 'path'

export default defineConfig({
  build: {
    // ========== 构建目标 ==========

    /**
     * target - 构建目标环境
     * 指定生成的 JavaScript 版本
     * 默认: 'modules' - 支持原生 ES 模块的浏览器
     */
    target: 'modules',
    // target: 'es2015',     // ES2015
    // target: 'es2016',     // ES2016
    // target: 'es2017',     // ES2017
    // target: 'es2018',     // ES2018
    // target: 'es2019',     // ES2019
    // target: 'es2020',     // ES2020
    // target: 'esnext',     // 最新 ES 特性
    // target: ['es2015', 'edge88', 'firefox78', 'chrome87', 'safari14'],  // 浏览器列表

    // ========== 模块预加载 ==========

    /**
     * modulePreload - 是否启用模块预加载
     * 生成 <link rel="modulepreload"> 标签提高性能
     */
    modulePreload: {
      polyfill: true,     // 是否自动注入模块预加载 polyfill
      resolveDependencies: (filename, deps, context) => {
        // 自定义解析依赖关系
        if (filename.includes('router')) {
          // 为路由文件添加额外的预加载依赖
          return [...deps, './src/views/Home.vue', './src/views/About.vue']
        }
        return deps
      }
    },
    // modulePreload: false,  // 完全禁用

    /**
     * polyfillModulePreload - 是否自动注入模块预加载 polyfill
     * 为不支持 modulepreload 的浏览器提供兼容
     * 已移至 modulePreload.polyfill
     */
    // polyfillModulePreload: true,  // 旧版配置

    // ========== 输出目录 ==========

    /**
     * outDir - 构建输出目录
     * 默认: 'dist'
     */
    outDir: 'dist',
    // outDir: 'build',
    // outDir: '../server/public',  // 输出到其他位置

    /**
     * assetsDir - 静态资源输出目录
     * 相对于 outDir 的路径
     * 默认: 'assets'
     */
    assetsDir: 'assets',
    // assetsDir: 'static',
    // assetsDir: '',  // 直接放在 outDir 根目录

    // ========== 资源内联限制 ==========

    /**
     * assetsInlineLimit - 资源内联为 base64 URL 的阈值（字节）
     * 小于此值的资源会被内联，大于此值的会作为文件复制
     * 默认: 4096 (4KB)
     */
    assetsInlineLimit: 4096,
    // assetsInlineLimit: 0,     // 禁用内联
    // assetsInlineLimit: 8192,  // 8KB

    // ========== CSS 配置 ==========

    /**
     * cssCodeSplit - 是否启用 CSS 代码分割
     * 为异步 chunk 生成单独的 CSS 文件
     * 默认: true
     */
    cssCodeSplit: true,
    // cssCodeSplit: false,  // 所有 CSS 合并到一个文件

    /**
     * cssTarget - CSS 压缩的目标浏览器
     * 用于兼容旧浏览器，避免现代 CSS 语法导致错误
     */
    cssTarget: 'modules',
    // cssTarget: ['chrome61', 'safari11'],  // 特定浏览器目标

    /**
     * cssMinify - CSS 压缩器
     * 默认使用 esbuild（更快）或 cssnano
     */
    cssMinify: 'esbuild',
    // cssMinify: 'lightningcss',  // 实验性
    // cssMinify: false,           // 禁用 CSS 压缩

    // ========== Sourcemap 配置 ==========

    /**
     * sourcemap - 是否生成 sourcemap 文件
     * 用于调试构建后的代码
     */
    sourcemap: false,
    // sourcemap: true,        // 生成独立的 .map 文件
    // sourcemap: 'inline',    // 内联在文件中
    // sourcemap: 'hidden',    // 生成但不包含引用

    // ========== Rollup 选项 ==========

    /**
     * rollupOptions - 直接传递给 Rollup 的配置
     * 用于高级定制构建过程
     */
    rollupOptions: {
      /**
       * input - 入口文件
       * 默认: index.html
       */
      input: {
        main: path.resolve(__dirname, 'index.html'),
        about: path.resolve(__dirname, 'about.html'),
        // 多页面应用配置
        // admin: path.resolve(__dirname, 'admin.html')
      },

      /**
       * output - 输出配置
       */
      output: {
        // chunk 文件命名
        chunkFileNames: 'js/[name]-[hash].js',
        entryFileNames: 'js/[name]-[hash].js',
        assetFileNames: (assetInfo) => {
          // 资源文件命名
          const extType = assetInfo.name.split('.')[1]
          if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
            return `images/[name]-[hash][extname]`
          }
          if (/woff|woff2|eot|ttf|otf/i.test(extType)) {
            return `fonts/[name]-[hash][extname]`
          }
          return `assets/[name]-[hash][extname]`
        },

        // 手动分块配置
        manualChunks: (id) => {
          // 将 node_modules 中的依赖分组
          if (id.includes('node_modules')) {
            if (id.includes('vue')) {
              return 'vue'  // Vue 相关单独打包
            }
            if (id.includes('lodash') || id.includes('ramda')) {
              return 'utils'  // 工具库打包
            }
            if (id.includes('axios') || id.includes('fetch')) {
              return 'network'  // 网络请求库
            }
            return 'vendor'  // 其他第三方库
          }
        },

        // 全局变量配置（库模式）
        globals: {
          vue: 'Vue',
          react: 'React',
          'react-dom': 'ReactDOM'
        }
      },

      /**
       * external - 外部依赖
       * 这些依赖不会被打包，需要在运行时提供
       */
      external: ['vue', 'react', 'react-dom'],

      /**
       * plugins - 额外的 Rollup 插件
       */
      plugins: [
        // 自定义 Rollup 插件
        // myCustomPlugin()
      ],

      /**
       * treeshake - 摇树优化配置
       */
      treeshake: {
        preset: 'recommended',
        annotations: true,
        moduleSideEffects: 'no-external',
        propertyReadSideEffects: true
      },

      /**
       * context - 顶级变量上下文
       */
      context: 'window',

      /**
       * preserveEntrySignatures - 保留入口签名
       */
      preserveEntrySignatures: 'strict'
    },

    // ========== CommonJS 选项 ==========

    /**
     * commonjsOptions - CommonJS 模块转换选项
     */
    commonjsOptions: {
      // 是否将动态 require 转换为 import
      dynamicRequireTargets: [
        './src/static/data.json',  // 动态引入的文件
        './src/locales/*.json'     // 通配符匹配
      ],

      // 排除的文件
      exclude: ['node_modules/ignored-package/**'],

      // 包含的文件
      include: [
        'node_modules/**',
        'src/**/*.cjs'
      ],

      // 忽略的依赖
      ignore: ['conditional-runtime-dependency'],

      // 忽略尝试导入不存在的导出
      ignoreTryCatch: false,

      // 是否将 require 调用转换为 import
      requireReturnsDefault: 'auto',

      // 严格模式
      strictRequires: true,

      // 转换混合模块
      transformMixedEsModules: true
    },

    // ========== 动态导入变量选项 ==========

    /**
     * dynamicImportVarsOptions - 动态导入变量选项
     * 控制包含变量的动态导入
     */
    dynamicImportVarsOptions: {
      // 警告限制
      warnOnError: false,

      // 排除的文件
      exclude: [/node_modules/]
    },

    // ========== 库模式 ==========

    /**
     * lib - 库模式配置
     * 用于构建库而不是应用
     */
    lib: {
      // 入口文件
      entry: path.resolve(__dirname, 'src/lib/main.js'),
      // entry: ['./src/lib1.js', './src/lib2.js'],  // 多个入口

      // 库名称
      name: 'MyLib',

      // 输出文件名格式
      fileName: (format, entryName) => {
        if (format === 'es') {
          return `${entryName}.mjs`
        }
        if (format === 'cjs') {
          return `${entryName}.cjs`
        }
        if (format === 'umd') {
          return `${entryName}.umd.js`
        }
        return `${entryName}.js`
      },
      // fileName: 'my-lib',  // 简单格式

      // 输出格式
      formats: ['es', 'cjs', 'umd'],
      // formats: ['es'],  // 仅 ES 模块

      // 全局变量（UMD 格式需要）
      // 当 formats 包含 'umd' 或 'iife' 时，需要指定全局变量名
    },

    // ========== 清单文件 ==========

    /**
     * manifest - 是否生成构建清单文件
     * 包含所有生成文件的映射，用于服务器端渲染等
     */
    manifest: false,
    // manifest: true,  // 生成 manifest.json
    // manifest: 'manifest.json',  // 自定义文件名

    /**
     * ssrManifest - 是否生成 SSR 清单文件
     * 用于服务端渲染时预加载资源
     */
    ssrManifest: false,
    // ssrManifest: true,  // 生成 ssr-manifest.json

    // ========== SSR 配置 ==========

    /**
     * ssr - 服务端渲染构建配置
     */
    ssr: false,
    // ssr: true,  // 启用 SSR 构建
    // ssr: 'src/entry-server.js',  // 自定义 SSR 入口

    // ========== 资源发射 ==========

    /**
     * emitAssets - 是否发射资源文件
     * 默认: true
     */
    emitAssets: true,
    // emitAssets: false,  // 不输出资源文件

    /**
     * ssrEmitAssets - SSR 构建时是否发射资源文件
     * 默认: false
     */
    ssrEmitAssets: false,
    // ssrEmitAssets: true,  // SSR 构建也输出资源

    // ========== 压缩配置 ==========

    /**
     * minify - JavaScript 压缩器
     * 默认: 'esbuild'（更快）
     */
    minify: 'esbuild',
    // minify: 'terser',    // 使用 Terser
    // minify: 'none',      // 禁用压缩
    // minify: false,       // 同 'none'

    /**
     * terserOptions - Terser 压缩选项
     * 仅当 minify: 'terser' 时生效
     */
    terserOptions: {
      compress: {
        drop_console: true,     // 移除 console
        drop_debugger: true,    // 移除 debugger
        pure_funcs: ['console.log']  // 移除特定函数
      },
      mangle: {
        // 混淆选项
        properties: {
          regex: /^_/  // 只混淆下划线开头的属性
        }
      },
      format: {
        comments: false  // 移除注释
      }
    },

    // ========== 输出控制 ==========

    /**
     * write - 是否将构建结果写入磁盘
     * 默认: true
     */
    write: true,
    // write: false,  // 仅生成不写入（用于编程式构建）

    // ========== 目录清理 ==========

    /**
     * emptyOutDir - 构建前是否清空输出目录
     * 默认: true（如果 outDir 在 root 内）
     */
    emptyOutDir: true,
    // emptyOutDir: false,  // 保留现有文件

    /**
     * copyPublicDir - 是否复制 publicDir 到 outDir
     * 默认: true
     */
    copyPublicDir: true,
    // copyPublicDir: false,  // 不复制 public 目录

    // ========== 构建报告 ==========

    /**
     * reportCompressedSize - 是否报告压缩后的大小
     * 默认: true
     */
    reportCompressedSize: true,
    // reportCompressedSize: false,  // 禁用大小报告

    /**
     * chunkSizeWarningLimit - chunk 大小警告限制（KB）
     * 默认: 500
     */
    chunkSizeWarningLimit: 500,
    // chunkSizeWarningLimit: 1000,  // 1MB
    // chunkSizeWarningLimit: false, // 禁用警告

    // ========== 监听模式 ==========

    /**
     * watch - 构建监听模式配置
     * 启用后会在文件变化时重新构建
     */
    watch: null,
    // watch: {},  // 启用监听模式使用默认配置
    // watch: {
    //   include: 'src/**',  // 监听的文件
    //   exclude: 'node_modules/**',  // 排除的文件
    //   clearScreen: false,  // 不清屏
    //   skipWrite: true     // 不写入磁盘（仅内存）
    // }
  }
})